home *** CD-ROM | disk | FTP | other *** search
- /*
- UPDATE.C
- Copyright (C) Seven Valleys Software 1985,1987,1988
- Written for Seven Valleys Software by Cheyenne Wills &
- Released For Public Distribution
- All Rights Reserved
-
- Permission is granted to freely distribute this code, but not for
- profit, provided that this notice and the following disclaimer are
- included in their entirety and without modifications of any sort. This
- work may not be sold, or modified and sold, or included in any other
- work to be sold, (except for a nominal media charge), without the
- written permission of the author.
-
- Permission is granted to modify the source code and distribute it in
- modified form PROVIDED that the authors of any modifications identify
- themselves with name and address following this header and that all such
- modifications are clearly indicated as to location and purpose, with
- descriptive comments that clearly indicate modified lines.
-
- The author would appreciate hearing of any modifications that may be
- made, but makes no guarantees that such modifications will be
- distributed with future releases of this program.
-
- Author's address:
-
- Cheyenne C. Wills
- 12 West Locust St.
- Mechanicsburg, Pa. 17055
- (717) 697-5198
-
- Written for
- Seven Valley's Software
- P.O. Box 99
- Glen Rock, Pa 17327
-
- Disclaimer:
-
- No guarantees or warranties of any kind: This code is distributed
- "AS IS" without any warranty of any kind, either expressed or implied,
- including, but not limited to the implied warranties of merchantability
- and fitness for a particular purpose. You are soley responsible for the
- selection of the program to achieve your intended results and for the
- results actually obtained. Should the program prove defective, you (and
- not the author) assume the entire cost of all necessary servicing,
- repair, or correction.
-
- Neither the author nor anyone else who has been involved in the
- creation, production or delivery of this program shall be liable for any
- direct, indirect, consequential or incidental damages arising out of the
- use or inability to use this program.
-
- History:
- Version Date Author Reason
- ------- -------- ------ ---------------------------------------------
- 1.0 08/01/84 CCW Written for Seven Valleys Software
- 1.1 08/17/85 CCW Add -i option, and online doc.
- 1.2 01/15/88 CCW Corrected some minor errors.
- 2.0 11/23/88 CCW Convert library calls to ANSI compatible
- */
-
- char *VERSION = "UPDATE V2.0\n";
- char *COPYR = "Copyright (C) Seven Valleys Software 1985,1987,1988\n";
-
- /*
- update <file1> <file2> [<file3>] [options]
- Where:
- <file1> is the name of the file to be updated
- <file2> is the name of the delta deck
- <file3> is the name of the output file (defaults to $<file1>)
-
- [options]
-
- -p Print a brief update log to PRN
- -pf Print a Full log (each update is listed) to PRN
-
- -l [<file>] List a brief update log to <file> (default is UPDATE.LOG)
- -lf [<file>] List a Full update log to <file> (default is UPDATE.LOG)
-
- -s[S,I] Generates sequences numbers starting with S and incremented
- by I. S defaults to 10000 and I defaults to S.
- ---- The following options control if the sequence numbers already
- ---- exist in the input file.
- -xi Input file contains sequence numbers as the first "word"
- of each line. (ex: 10000 10 rem fist line).
- -xio[S,I] Input file contains sequence numbers as the first "word"
- output file will also contain sequence numbers as the
- first word. If S is specified, then the output will
- be resequenced starting with S. I (the increment)
- defaults to S.
- -xo[S,I] Resequence the output file.
-
- -c Control file. <file2> is the name of a control file
- <file1> is the name of the output file.
- <file3> is unused.
- Each line of the control file contains as its
- first "word" the extension of an input file.
- the first line must be the extension of base file.
- ex:
- >> DIR COMPARE.* -->
- COMPARE.CTL
- COMPARE.V00
- COMPARE.V01
- +---------------COMPARE.CTL-------------------+
- | V00 Base of COMPARE.C |
- | V01 Add -i option and online doc |
- +---------------------------------------------+
- To generate COMPARE.C
- UPDATE COMPARE.C COMPARE.CTL -c
-
- ------------ following for aide with editor shells only -----------
- -i Generate a sequence file to be used by COMPARE
- on the last pass generate a external sequence file.
-
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <ctype.h>
-
- #define TRUE 1
- #define FALSE 0
- #define ERR (-2)
-
- #define MAXLEN 256
- #define IOBUFSZ 4096
-
- FILE *outfile; /* Output file */
- FILE *srcfile; /* Source file */
- FILE *updtfile; /* Update file */
- FILE *logfile; /* Update logfile */
- FILE *listfile; /* Update logfile */
- FILE *ctlfile; /* Control file */
- FILE *console; /* Were to send messages */
- FILE *seqf; /* Sequence file */
-
- char *files[3]; /* Pointers to the names of the files */
- char *Lfile; /* Pointer to the Logfile */
-
- char updtname[64]; /* Update deck name */
- char outname[64]; /* Output file name */
- char ctlname[64]; /* Control file name */
- char srcname[64]; /* Source name */
- char seqname[64]; /* Sequence file name */
-
- char sourcepath[51];
- char sourcename[20]; /* Filename of source */
- char sourceext[5];
-
- char buf[MAXLEN]; /* Line from the source file */
- char updtline[MAXLEN]; /* Line from the update file */
- char ctlrec[MAXLEN]; /* LIne from the control file */
-
- /* Switchs and flags */
- char Log, /* Log updates to a file */
- PLog, /* Log file to print */
- FLog, /* Log file to file */
- PLogF, /* Full listing to print */
- FLogF, /* Full listing to file */
- SaveFull, /* Save the Full flag during ctl processing */
- XSeqf, /* Put sequence numbers to external seq file */
- SaveXSeqf, /* Save XSeqf flag */
- Pexternal, /* Leave sequences numbers on the output file */
- SavePextern, /* Save external on output */
- Linepushed, /* A line was pushed back in the source file */
- Ctlf, /* Using a control file */
- Rseq, /* Resequence the output file */
- Full, /* After updating the file print a full listing */
- ToAFile, /* Loging to a file */
- Print = 0; /* Log file going to print, so check for pages */
-
- /* Method of obtaining sequence numbers */
- #define XTERNAL 0 /* Sequence numbers are contained in the file */
- #define USERSEQ 1 /* User specified sequence numbers */
- #define GENSEQ 2 /* Sequence numbers are equal to record num */
- char Seqtype = GENSEQ;
-
- long int Seqstrt = 1; /* Starting sequence number */
- long int Seqincr = 1; /* Increment */
- long int Seqnum = 0; /* Sequence number from the file */
-
- long int Rseqstrt; /* Resequencing numbers */
- long int Rseqincr;
- long int Rseqnum;
-
- int updtcmd; /* The update command from the update control card */
- long int Seq1; /* Sequence numbers taken from a ucl card */
- long int Seq2;
- long int Seq3;
- long int Seq4;
-
- struct ctl { /* List of items taken from the control file */
- struct ctl *next; /* Next item */
- char ext[4]; /* Extension to use */
- } ctla, *ctlp; /* Anchor, and pointer */
-
- #define galloc(c) (struct c *)malloc(sizeof( struct c))
- int numupdates = 0; /* Number of updates found in the control file */
-
- #define LINESPERPAGE 66
- int curline = LINESPERPAGE+1;
-
- char *iobuf1;
- char *iobuf2;
- char *iobuf3;
-
- main(argc,argv)
- char **argv;
- int argc;
- {
- int i;
- char *cp;
- char *c;
-
- console=stdout;
- /* Handle the quiet option */
- if(strcmp(argv[argc-1],"-q")==0) {
- console=fopen("NUL","w");
- argc--;
- }
- else {
- fputs(VERSION,stderr); /* Put out our header for version */
- fputs(COPYR,stderr); /* Put out our header for version */
- fflush(stderr);
- }
-
- if(argc<3) {
- fputs("\nMission filename(s).\n",stderr);
- cmndformat();
- exit(12);
- }
-
- Lfile=NULL;
-
- for(argc--,i=0;argc;argc--) {
- cp=*++argv; /* Get the next token */
- if(*cp=='-') { /* Select an option */
- cp++; /* Point to the option */
- switch(tolower(*cp)) {
- case 'i':
- XSeqf++;
- break;
- case 'c': /* Control file */
- Ctlf++;
- Seqtype=USERSEQ;
- Seqincr=Seqstrt=10000;
- Seqnum=Seqstrt-Seqincr;
- break;
- case 'p': /* Send logfile to a printer */
- if(tolower(*(cp+1))=='f') PLogF++;
- PLog++;
- break;
- case 'l': /* Log the updates to a logfile */
- if(tolower(*(cp+1))=='f') FLogF++;
- if(argc-1) {
- Lfile=*++argv;
- argc--;
- if(*Lfile=='-') {
- Lfile="UPDATE.LOG";
- argv--;
- argc++;
- }
- }
- else Lfile="UPDATE.LOG";
- FLog++;
- break;
- case 's': /* Generate internal sequence numbers */
- cp++;
- Seqtype=USERSEQ;
- if(isdigit(*cp)) {
- cp+=stcd_l(cp,&Seqstrt);
- if(*cp==',') {
- cp++;
- stcd_l(cp,&Seqincr);
- }
- else Seqincr=Seqstrt;
- }
- else Seqincr=Seqstrt=10000;
- Seqnum=Seqstrt-Seqincr;
- break;
- case 'x': /* Use external sequence numbers */
- cp++;
- if(tolower(*cp)=='i') {
- Seqtype=XTERNAL;
- cp++;
- if(tolower(*cp)=='o') {
- Pexternal=TRUE;
- cp++;
- if(isdigit(*cp)) {
- Rseq=TRUE;
- cp+=stcd_l(cp,&Rseqstrt);
- if(*cp==',') {
- cp++;
- stcd_l(cp,&Rseqincr);
- }
- else Rseqincr=Rseqstrt;
- Rseqnum=Rseqstrt-Rseqincr;
- }
- }
- }
- else if(tolower(*cp)=='o') {
- Pexternal=TRUE;
- cp++;
- if(isdigit(*cp)) {
- Rseq=TRUE;
- cp+=stcd_l(cp,&Rseqstrt);
- if(*cp==',') {
- cp++;
- stcd_l(cp,&Rseqincr);
- }
- else Rseqincr=Rseqstrt;
- Rseqnum=Rseqstrt-Rseqincr;
- }
- }
- else if(*cp=='\0') Pexternal=TRUE;
- break;
- default: /* Error (unknow option) */
- fprintf(stderr,"\nInvalid option -%s\n",cp);
- cmndformat();
- exit(12);
- break;
- }
- }
- else if(i<3) files[i++]=cp; /* Point to the filename */
- }
- /* We need at least one files */
-
- if(i<1) { /* Tell about the error */
- fputs("\nMissing input filename.\n",stderr);
- cmndformat();
- exit(12);
- }
- parsename(files[0],sourcepath,sourcename,sourceext);
-
- /* If we are using a control file, and there wasn't a control file */
- /* defined, generate a default id */
- if(Ctlf) {
- if(i<2) buildname(ctlname,sourcepath,sourcename,"CTL");
- else strcpy(ctlname,files[1]);
- }
- else {
- if(i<2) { /* Tell about the error */
- fputs("\nMissing filename(s).\n",stderr);
- cmndformat();
- exit(12);
- }
- strcpy(updtname,files[1]);
- if(i==2) {
- int j;
- outname[0]='\0';
- c=outname;
- if(strlen(sourcepath)!=0) {
- strcat(outname,sourcepath);
- strcat(outname,"\\");
- c+=2;
- }
- strcat(outname,"$");
- c++;
- for(j=1,cp=sourcename;j<8 && *cp!='\0';j++,cp++)
- *c++=*cp;
- if(strlen(sourceext)!=0) {
- strcat(outname,".");
- strcat(outname,sourceext);
- }
- }
- else strcpy(outname,files[2]);
- }
- if(FLogF) { /* Handle the case of a full listing */
- FLog=0; /* Don't allow update log */
- Full++; /* Turn on full listing */
- if( (listfile=fopen(Lfile,"w"))==NULL) {
- fprintf(stderr,"\nUnable to open list file [%s]\n",Lfile);
- exit(12);
- }
- }
- if(PLogF) { /* Handle the case of a full listing going to the printer */
- PLog=0; /* Don't allow update log to printer */
- Full++;
- if( (listfile=fopen("PRN","w"))==NULL) {
- fprintf(stderr,"\nUnable to open list file [%s]\n","PRN");
- exit(12);
- }
- }
- /* Now open a log file */
- if(PLog||FLog) Log++;
-
- if(Log) {
- if(PLog) Lfile="PRN";
- if( (logfile=fopen(Lfile,"w"))==NULL) {
- fprintf(stderr,"\nUnable to open log file [%s]\n",Lfile);
- exit(12);
- }
- }
-
- /* Now start updating files */
- if( Ctlf ) { /* Process the update via control file */
- SaveFull = Full; /* save the full switch */
- SavePextern = Pexternal;
- SaveXSeqf = XSeqf;
- Full = 0; /* Always zero */
- if((ctlfile=fopen(ctlname,"r"))==NULL) {
- fprintf(stderr,"\nUnable to open control file [%s]\n",ctlname);
- exit(12);
- }
-
- ctlp = &ctla;
- ctlp->next=NULL;
- ctlp->ext[0]='\0';
-
- while( fgets(ctlrec,MAXLEN,ctlfile)!=NULL ) {
- if(ctlrec[0]=='*') continue; /* Skip comments */
- numupdates++; /* Increase number of updates */
- {
- char *p1, *p2;
- int i;
- p1 = ctlrec;
- p2 = (ctlp->ext);
- for(i=0;*p1 != '\n' && !isspace(*p1) && i<3;i++)
- *p2++ = *p1++;
- *p2 = '\0';
- }
- ctlp->next=galloc(ctl); /* Allocate the next item */
- ctlp=ctlp->next; /* Point to the next item */
- ctlp->next=NULL; /* Set this pointer to null*/
- ctlp->ext[0]='\0';
- }
- numupdates--; /* Exclude the base file */
- fclose(ctlfile);
-
- /* Get the base file */
- strcpy(srcname,sourcename); /* Get the source name */
- strcat(srcname,".");
- strcat(srcname,ctla.ext); /* Concat the extension */
-
- for(ctlp=ctla.next,i=0;i<numupdates-1;i++,ctlp=ctlp->next) {
- buildname(updtname,sourcepath,sourcename,ctlp->ext);
- if(i%2) strcpy(outname,"$updtw2$.tmp");
- else strcpy(outname,"$updtw1$.tmp");
- if( (srcfile=fopen(srcname,"r"))==NULL) {
- fprintf(stderr,"Unable to open source file [%s]\n",srcname);
- exit(12);
- }
- if( (updtfile=fopen(updtname,"r"))==NULL) {
- fprintf(stderr,"Unable to open update file [%s]\n",updtname);
- exit(12);
- }
- if( (outfile=fopen(outname,"w"))==NULL) {
- fprintf(stderr,"Unable to open output file [%s]\n",outname);
- exit(12);
- }
- Rseqnum=Rseqstrt-Rseqincr;
- Seqnum=Seqstrt-Seqincr;
- Pexternal=TRUE;
- fprintf(console,"Applying [%s]\n",updtname);
- update();
- if(i%2) unlink("$updtw1$.tmp");
- else unlink("$updtw2$.tmp");
- Rseqnum=Rseqstrt-Rseqincr;
- Seqnum=Seqstrt-Seqincr;
- Pexternal=FALSE;
- Seqtype=XTERNAL;
- strcpy(srcname,outname);
- }
- buildname(outname,sourcepath,sourcename,sourceext);
- buildname(updtname,sourcepath,sourcename,ctlp->ext);
- Full=SaveFull; /* Restore the full listing flag */
- Pexternal=SavePextern;
- XSeqf=SaveXSeqf;
- }
- else buildname(srcname,sourcepath,sourcename,sourceext);
-
- if( (srcfile=fopen(srcname,"r"))==NULL) {
- fprintf(stderr,"Unable to open source file [%s]\n",srcname);
- exit(12);
- }
- if( (updtfile=fopen(updtname,"r"))==NULL) {
- fprintf(stderr,"Unable to open update file [%s]\n",updtname);
- exit(12);
- }
- if( (outfile=fopen(outname,"w"))==NULL) {
- fprintf(stderr,"Unable to open output file [%s]\n",outname);
- exit(12);
- }
- fprintf(console,"Applying [%s]\n",updtname);
- if(XSeqf) {
- Pexternal++;
- newext(seqname,outname,"seq");
- seqf=fopen(seqname,"wb");
- }
- update();
- if(XSeqf) fclose(seqf);
-
- if( Ctlf ) { unlink("$updtw1$.tmp"); unlink("$updtw2$.tmp"); }
- if( Log ) {
- fflush(logfile);
- fclose(logfile);
- }
- if( Full ) {
- fflush(listfile);
- fclose(listfile);
- }
- }
- /*---------------------------------------------------------------------*/
- /* srcfile = file to be updated */
- /* updtfile = update deck */
- /* outfile = output file */
- /* */
- /* if Seqtype = XTERNAL then we pull the sequence numbers from the */
- /* front of each record from srcfile. Otherwise we generate our own */
- /* numbers. If Pexternal is true, then we write out the sequence */
- /* numbers along with the output data. */
- /* */
- /*---------------------------------------------------------------------*/
- update()
- {
- char Exit;
- char Firstime;
-
- updtcmd='*';
- Exit=FALSE;
- Firstime=TRUE;
-
- iobuf1=malloc(IOBUFSZ);
- iobuf2=malloc(IOBUFSZ);
- iobuf3=malloc(IOBUFSZ);
- if (iobuf1) setvbuf(srcfile,iobuf1,_IOFBF,IOBUFSZ);
- if (iobuf2) setvbuf(updtfile,iobuf2,_IOFBF,IOBUFSZ);
- if (iobuf3) setvbuf(outfile,iobuf3,_IOFBF,IOBUFSZ);
-
- getupdt(); /* Go prime the buffer */
- while(!Exit) {
- updtcmd=getcmd(); /* Get a command from input */
- if(Log) fprintf(logfile,"%s",updtline);
- switch(updtcmd) {
-
- /* End Of File on the Update deck */
- case EOF:
- while( getline()!=EOF ) writeupdt(Seqnum);
- Exit=1; /* Exit the main loop */
- break;
-
- /* Delete Lines from the input file */
- case 'D':
- /* Copy upto arg1 */
- if( copyin(Seq1)==ERR) {
- reset();
- break;
- }
- /* Delete the lines */
- if( delin(Seq2)==ERR) {
- reset();
- break;
- }
- getupdt();
- break;
-
- /* Insert lines from the update deck */
- case 'I':
- /* Copy upto arg1 */
- if( copyin(Seq1)==ERR) {
- reset();
- break;
- }
- if(!Linepushed) break;
- getline();
- writeupdt(Seqnum); /* Now copy the matching record */
- copyup(Seq2,Seq3); /* Copy from update deck */
- break;
-
- /* Replace from the update deck */
- case 'R': /* Replace from the update deck */
- /* Copy upto arg1 */
- if( copyin(Seq1)==ERR) {
- reset();
- break;
- }
- /* Delete the lines */
- if( delin(Seq2)==ERR) {
- reset();
- break;
- }
- copyup(Seq3,Seq4); /* Copy from update deck */
- break;
-
- /* Just a comment */
- case '*': /* Ignore comments */
- getupdt();
- break;
- case 'S':
- if(!Firstime) {
- fprintf(stderr,"\n./ S valid only as first card in update file\n");
- getupdt();
- break;
- }
- Rseqstrt=Seq1;
- Rseqincr=Seq2;
- Rseqnum=Rseqstrt-Rseqincr;
- getupdt();
- break;
- case 0:
- break;
- case ERR:
- default:
- fprintf(stderr,"\nInvalid update control record:\n%s\n",
- updtline);
- getupdt();
- break;
- }
- Firstime=FALSE;
- }
-
- fclose(srcfile); /* Close the source file */
- fclose(updtfile); /* Close the update deck */
- fclose(outfile); /* Close the updated file */
-
- if(iobuf1!=NULL) free(iobuf1);
- if(iobuf2!=NULL) free(iobuf2);
- if(iobuf3!=NULL) free(iobuf3);
- iobuf1=iobuf2=iobuf3=NULL;
- }
- int getcmd() /* Return the command from the update deck */
- {
- char *c;
- char c1;
-
- if(updtcmd==EOF) return EOF; /* Return eof char */
- c = updtline;
- if(*c++ != '.') return ERR;
- if(*c++ != '/') return ERR;
- if(!isspace(*c)) return ERR;
- while(isspace(*c)) c++;
- if( !isspace(*(c+1)) && *(c+1)!='\n') return ERR;
- c1=toupper(*c); /* not a command */
- c++;
- switch(c1) {
- /* Process a possible valid command */
-
- case 'D': /* ./ D Seqno1 [Seqno2] [$] */
- switch(getnum(&c,&Seq1)) {
- case 0: /* Valid number */
- break;
-
- default:
- return ERR;
- break;
- }
- switch(getnum(&c,&Seq2)) {
- case 0:
- return 'D';
- break;
- default:
- Seq2=Seq1;
- return 'D';
- break;
- }
- break;
- case 'I': /* ./ I Seqno [$ [seqstrt [seqincr]]] */
- switch(getnum(&c,&Seq1)) {
- case 0:
- break;
- default:
- return ERR;
- break;
- }
- switch(getnum(&c,&Seq2)) { /* This must be a $ */
- case '$':
- c++;
- break;
- default:
- Seq2=Seq1+100;
- Seq3=100;
- return 'I';
- break;
- }
- switch(getnum(&c,&Seq2)) { /* Now we will try to get a number */
- case 0: /* Ok we got a number for strtseq */
- break;
- default:
- Seq2=Seq1+100;
- Seq3=100;
- return 'I';
- break;
- }
- switch(getnum(&c,&Seq3)) { /* Try for seqincr */
- case 0: /* Ok return with the number.. */
- return 'I';
- break;
- default: /* Otherwise set the default.. */
- Seq3=Seq1-Seq2;
- return 'I';
- break;
- }
- break;
- case 'R': /* ./ R Seqno1 [Seqno2] [$ [Seqstrt [Seqincr]]] */
- switch(getnum(&c,&Seq1)) {
- case 0:
- break;
- default:
- return ERR;
- break;
- }
- switch(getnum(&c,&Seq2)) {
- case 0:
- break;
- case '$':
- Seq2=Seq1;
- break;
- default:
- Seq2=Seq1;
- Seq3=Seq1+100;
- Seq4=100;
- return 'R';
- break;
- }
- switch(getnum(&c,&Seq3)) {
- case '$':
- c++;
- break;
- default:
- Seq3=Seq1+100;
- Seq4=100;
- return 'R';
- break;
- }
- switch(getnum(&c,&Seq3)) {
- case 0:
- break;
- default:
- Seq3=Seq1+100;
- Seq4=100;
- return 'R';
- break;
- }
- switch(getnum(&c,&Seq4)) {
- case 0:
- return 'R';
- break;
- default:
- Seq4=Seq1-Seq3;
- return 'R';
- break;
- }
- break;
- case 'S': /* ./ S [Seqstrt [Seqincr]] */
- switch(getnum(&c,&Seq1)) {
- case 0: /* Valid number */
- break;
-
- default:
- Seq2=Seq1=10000;
- return 'S';
- break;
- }
- switch(getnum(&c,&Seq2)) {
- case 0:
- return 'S';
- break;
- default:
- Seq2=Seq1;
- return 'S';
- break;
- }
- break;
- case '*': /* ./ * [comment] */
- return '*';
- break;
-
- default:
- return NULL;
- break;
- }
- }
-
-
- getupdt()
- {
- if( fgets(updtline,MAXLEN,updtfile) == NULL ) updtcmd=EOF;
- }
-
- reset() /* Here to reset after an error */
- {
- do getupdt(); while(!iscommand());
- }
-
- iscommand() /* Look for special strings in the input from the update file */
- {
- char *c;
-
- if(updtcmd==EOF) return TRUE; /* EOF is a command */
-
- c = updtline;
- if(*c++ != '.') return FALSE;
- if(*c++ != '/') return FALSE;
- if(!isspace(*c)) return FALSE;
- while( isspace(*c) ) c++;
- if( !isspace(*(c+1)) && *(c+1)!='\n') return FALSE;
- switch(toupper(*c)) { /* not a command */
-
- case 'D': return TRUE; break;
- case 'I': return TRUE; break;
- case 'R': return TRUE; break;
- case 'S': return TRUE; break;
- case '*': return TRUE; break;
-
- default: return FALSE; break;
- }
- }
-
-
- copyup(s1,s2) /* Copy from the update file */
- long int s1,s2;
- {
- if(Log) fputs(" ...Inserting:\n",logfile);
- for(;;) {
- getupdt();
- if(iscommand()) break;
- strcpy(buf,updtline);
- if(Log) fprintf(logfile,"\t%s",updtline);
- writeupdt(s1); /* Write the record back */
- buf[0]='\0'; /* Clear the buffer */
- s1+=s2;
- }
- }
- writeupdt(s)
- long int s;
- {
- if(Full) {
- pagechk();
- if(Rseq) fprintf(listfile," %ld > ",Rseqnum);
- else fprintf(listfile," %ld > ",s);
- fputs(buf,listfile);
- }
- if(Rseq) {
- Rseqnum += Rseqincr;
- fprintf(outfile,"%ld ",Rseqnum);
- }
- else if(Pexternal) {
- if(XSeqf) fwrite(&s,sizeof(s),1,seqf);
- else fprintf(outfile,"%ld ",s);
- }
- fputs(buf,outfile);
- }
- copyin(n) /* Copy upto n */
- long int n;
- {
- while( (getline()!=EOF) && Seqnum != n) {
- if(Seqnum > n) { /* Handle a sequence error */
- fprintf(stderr,"\nSequence error in update [%s]\n",updtname);
- fprintf(stderr,"Input file sequence number: %ld Update sequence number %ld\n",
- Seqnum,n);
- fprintf(stderr,"Update record:\n\t%s\n",updtline);
- return ERR;
- }
- writeupdt(Seqnum); /* Write a record back */
- }
- if(Seqnum == n) pushline();
- else return EOF;
- }
- delin(n) /* Delete upto and including n */
- long int n;
- {
- if(Log) fputs(" ...Deleting:\n",logfile);
- while( (getline()!=EOF) && Seqnum != n) {
- if(Log) fprintf(logfile,"\t%s",buf);
- if(Seqnum>n) { /* Handle sequence error */
- fprintf(stderr,"\nSequence error in update [%s]\n",updtname);
- fprintf(stderr,"Input file sequence number: %ld Update sequence number %ld\n",
- Seqnum,n);
- fprintf(stderr,"Update record:\n\t%s\n",updtline);
- return ERR;
- }
- }
- if(Seqnum==n) {
- if(Log) fprintf(logfile,"\t%s",buf);
- return;
- }
- else return EOF;
- }
- pushline() /* Mark a line for future use */
- {
- Linepushed=1;
- }
- getline() /* Get a line from the input file. */
- {
- char *c;
- char wrkbuf[MAXLEN];
- if(Linepushed) {
- Linepushed=0;
- return;
- }
- if(fgets(wrkbuf,MAXLEN,srcfile)==NULL) return EOF;
-
- c=wrkbuf;
-
- switch(Seqtype) {
- case XTERNAL: /* Sequence numbers are part of the file */
- c+=stcd_l(wrkbuf,&Seqnum);
- if(*c!='\n') ++c; /* Handle a null line */
- break;
- case USERSEQ:
- case GENSEQ:
- Seqnum += Seqincr; /* Increment sequence number */
- break;
- default: break;
- }
- strcpy(buf,c); /* Copy from the input buffer to the string buffer */
- return 0;
- }
-
- stcd_l(s,n)
- char *s;
- long *n;
- {
- int i; /* Number of characters we picked off */
- for(i=0,*n=0L;isdigit(*s);s++,i++) *n=(*n * 10)+ (*s-'0');
- return i;
- }
-
- getnum(s,n)
- char **s;
- long *n;
- {
- int c;
- while( isspace(**s) ) (*s)++;
- if( isdigit(**s) ) { /* Process a number .. */
- (*s)+=stcd_l(*s,n);
- c=0;
- }
- else c = (**s) ? **s : 1;
- return c; /* Return the character that we stopped on.. */
- }
- pagechk() /* Check to see if we are to do a page eject if we are printing */
- {
- if(curline++ < LINESPERPAGE) return;
- fputc('\f',listfile);
- fputs(VERSION,listfile);
- curline=3;
- }
- parsename(source,path,name,ext)
- char *source;
- char *path;
- char *name;
- char *ext;
- {
- int i;
-
- path[0]=name[0]=ext[0]=0;
- for(i=strlen(source);i;i--) {
- if(source[i]=='.') {
- strcpy(ext,&source[i+1]);
- source[i]=0;
- }
- else if(source[i]==':' ||
- source[i]=='\\' ||
- source[i]=='/') {
- strcpy(name,&source[i+1]);
- source[i]=0;
- }
- }
- if(name[0]) strcpy(path,source);
- else strcpy(name,source);
- }
- buildname(new,path,name,ext)
- char new[];
- char *path;
- char *name;
- char *ext;
- {
-
- new[0]='\0';
- if(strlen(path)!=0) {
- strcat(new,path);
- strcat(new,"\\");
- }
- strcat(new,name);
- if(strlen(ext)!=0) {
- strcat(new,".");
- strcat(new,ext);
- }
- }
- newext(fbuff,filename,newext)
- char *fbuff;
- char *filename;
- char *newext;
- {
- register char *in, *out;
- in = filename;
- out = fbuff;
- while ( *in && *in != '.' )
- *out++ = *in++;
- *out++ = '.';
- in = newext;
- while ( *in )
- *out++ = *in++;
- return;
- }
- cmndformat()
- {
- fputs("update <file1> <file2> [<file3>] [options]\n",console);
- fputs("Where:\n",console);
- fputs(" <file1> is the name of the file to be updated\n",console);
- fputs(" <file2> is the name of the delta deck\n",console);
- fputs(" <file3> is the name of the output file (defaults to $<file1>)\n",console);
- fputs("\n",console);
- fputs("[options]\n",console);
- fputs("\n",console);
- fputs(" -p Print a brief update log to PRN\n",console);
- fputs(" -pf Print a Full log (each update is listed) to PRN\n",console);
- fputs("\n",console);
- fputs(" -l [<file>] List a brief update log to <file> (default is UPDATE.LOG)\n",console);
- fputs(" -lf [<file>] List a Full update log to <file> (default is UPDATE.LOG)\n",console);
- fputs("\n",console);
- fputs(" -s[S,I] Generates sequences numbers starting with S and incremented\n",console);
- fputs(" by I. S defaults to 10000 and I defaults to S.\n",console);
- fputs("---- The following options control if the sequence numbers already\n",console);
- fputs("---- exist in the input file.\n",console);
- fputs(" -xi Input file contains sequence numbers as the first \"word\"\n",console);
- fputs(" of each line. (ex: 10000 10 rem fist line).\n",console);
- fputs(" -xio[S,I] Input file contains sequence numbers as the first \"word\"\n",console);
- fputs(" output file will also contain sequence numbers as the\n",console);
- fputs(" first word. If S is specified, then the output will\n",console);
- fputs(" be resequenced starting with S. I (the increment)\n",console);
- fputs(" defaults to S.\n",console);
- fputs(" -xo[S,I] Resequence the output file.\n",console);
- fputs("\n",console);
- fputs(" -c Control file. <file2> is the name of a control file\n",console);
- fputs(" <file1> is the name of the output file.\n",console);
- fputs(" <file3> is unused.\n",console);
- fputs(" Each line of the control file contains as its\n",console);
- fputs(" first \"word\" the extension of an input file.\n",console);
- fputs(" the first line must be the extension of base file.\n",console);
- fputs(" ex:\n",console);
- fputs(" >> DIR COMPARE.* -->\n",console);
- fputs(" COMPARE.CTL\n",console);
- fputs(" COMPARE.V00\n",console);
- fputs(" COMPARE.V01\n",console);
- fputs(" +---------------COMPARE.CTL-------------------+\n",console);
- fputs(" | V00 Base of COMPARE.C |\n",console);
- fputs(" | V01 Add -i option and online doc |\n",console);
- fputs(" +---------------------------------------------+\n",console);
- fputs(" To generate COMPARE.C\n",console);
- fputs(" UPDATE COMPARE.C COMPARE.CTL -c\n",console);
- fputs("\n",console);
- fputs("------------ following for aide with editor shells only -----------\n",console);
- fputs(" -i Generate a sequence file to be used by COMPARE\n",console);
- fputs(" on the last pass generate a external sequence file.\n",console);
- }
-